﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Text;
using HslCommunication.BasicFramework;
using HslCommunication.Reflection;
using HslCommunication.Serial;

namespace HslCommunication.Profinet.IDCard
{
	/// <summary>
	/// 基于SAM协议的串口通信类，支持读取身份证的数据信息，详细参见API文档<br />
	/// Network class implemented by Tcp based on the SAM protocol, which supports reading ID card data information, 
	/// see API documentation for details
	/// </summary>
	/// <example>
	/// 在使用之前需要实例化当前的对象，然后根据实际的情况填写好串口的信息，否则连接不上去。
	/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\SAMSerialSample.cs" region="Sample1" title="实例化操作" />
	/// 在实际的读取，我们一般放在后台进行循环扫描的操作，参见下面的代码
	/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\Profinet\SAMSerialSample.cs" region="Sample2" title="基本的读取操作" />
	/// </example>
	// Token: 0x0200009B RID: 155
	public class SAMSerial : SerialBase
	{
		/// <inheritdoc />
		// Token: 0x06000BA8 RID: 2984 RVA: 0x00044610 File Offset: 0x00042810
		protected override OperateResult<byte[]> SPReceived(SerialPort serialPort, bool awaitData)
		{
			List<byte> list = new List<byte>();
			OperateResult<byte[]> operateResult;
			for (;;)
			{
				operateResult = base.SPReceived(serialPort, awaitData);
				bool flag = !operateResult.IsSuccess;
				if (flag)
				{
					break;
				}
				list.AddRange(operateResult.Content);
				bool flag2 = SAMSerial.CheckADSCommandCompletion(list);
				if (flag2)
				{
					goto Block_2;
				}
			}
			return operateResult;
			Block_2:
			return OperateResult.CreateSuccessResult<byte[]>(list.ToArray());
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.IDCard.SAMTcpNet.ReadSafeModuleNumber" />
		// Token: 0x06000BA9 RID: 2985 RVA: 0x00044670 File Offset: 0x00042870
		[HslMqttApi]
		public OperateResult<string> ReadSafeModuleNumber()
		{
			byte[] send = SAMSerial.PackToSAMCommand(SAMSerial.BuildReadCommand(18, byte.MaxValue, null));
			OperateResult<byte[]> operateResult = base.ReadBase(send);
			bool flag = !operateResult.IsSuccess;
			OperateResult<string> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<string>(operateResult);
			}
			else
			{
				OperateResult operateResult2 = SAMSerial.CheckADSCommandAndSum(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<string>(operateResult2);
				}
				else
				{
					result = SAMSerial.ExtractSafeModuleNumber(operateResult.Content);
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.IDCard.SAMTcpNet.CheckSafeModuleStatus" />
		// Token: 0x06000BAA RID: 2986 RVA: 0x000446E8 File Offset: 0x000428E8
		[HslMqttApi]
		public OperateResult CheckSafeModuleStatus()
		{
			byte[] send = SAMSerial.PackToSAMCommand(SAMSerial.BuildReadCommand(18, byte.MaxValue, null));
			OperateResult<byte[]> operateResult = base.ReadBase(send);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<string>(operateResult);
			}
			else
			{
				OperateResult operateResult2 = SAMSerial.CheckADSCommandAndSum(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<string>(operateResult2);
				}
				else
				{
					bool flag3 = operateResult.Content[9] != 144;
					if (flag3)
					{
						result = new OperateResult(SAMSerial.GetErrorDescription((int)operateResult.Content[9]));
					}
					else
					{
						result = OperateResult.CreateSuccessResult();
					}
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.IDCard.SAMTcpNet.SearchCard" />
		// Token: 0x06000BAB RID: 2987 RVA: 0x00044788 File Offset: 0x00042988
		[HslMqttApi]
		public OperateResult SearchCard()
		{
			byte[] send = SAMSerial.PackToSAMCommand(SAMSerial.BuildReadCommand(32, 1, null));
			OperateResult<byte[]> operateResult = base.ReadBase(send);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<string>(operateResult);
			}
			else
			{
				OperateResult operateResult2 = SAMSerial.CheckADSCommandAndSum(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<string>(operateResult2);
				}
				else
				{
					bool flag3 = operateResult.Content[9] != 159;
					if (flag3)
					{
						result = new OperateResult(SAMSerial.GetErrorDescription((int)operateResult.Content[9]));
					}
					else
					{
						result = OperateResult.CreateSuccessResult();
					}
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.IDCard.SAMTcpNet.SelectCard" />
		// Token: 0x06000BAC RID: 2988 RVA: 0x00044824 File Offset: 0x00042A24
		[HslMqttApi]
		public OperateResult SelectCard()
		{
			byte[] send = SAMSerial.PackToSAMCommand(SAMSerial.BuildReadCommand(32, 2, null));
			OperateResult<byte[]> operateResult = base.ReadBase(send);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<string>(operateResult);
			}
			else
			{
				OperateResult operateResult2 = SAMSerial.CheckADSCommandAndSum(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<string>(operateResult2);
				}
				else
				{
					bool flag3 = operateResult.Content[9] != 144;
					if (flag3)
					{
						result = new OperateResult(SAMSerial.GetErrorDescription((int)operateResult.Content[9]));
					}
					else
					{
						result = OperateResult.CreateSuccessResult();
					}
				}
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.IDCard.SAMTcpNet.ReadCard" />
		// Token: 0x06000BAD RID: 2989 RVA: 0x000448C0 File Offset: 0x00042AC0
		[HslMqttApi]
		public OperateResult<IdentityCard> ReadCard()
		{
			byte[] send = SAMSerial.PackToSAMCommand(SAMSerial.BuildReadCommand(48, 1, null));
			OperateResult<byte[]> operateResult = base.ReadBase(send);
			bool flag = !operateResult.IsSuccess;
			OperateResult<IdentityCard> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<IdentityCard>(operateResult);
			}
			else
			{
				OperateResult operateResult2 = SAMSerial.CheckADSCommandAndSum(operateResult.Content);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<IdentityCard>(operateResult2);
				}
				else
				{
					result = SAMSerial.ExtractIdentityCard(operateResult.Content);
				}
			}
			return result;
		}

		/// <inheritdoc />
		// Token: 0x06000BAE RID: 2990 RVA: 0x00044932 File Offset: 0x00042B32
		public override string ToString()
		{
			return string.Format("SAMSerial[{0}:{1}]", base.PortName, base.BaudRate);
		}

		/// <summary>
		/// 将指令进行打包成可以发送的数据对象
		/// </summary>
		/// <param name="command">命令信息</param>
		/// <returns>字节数组</returns>
		// Token: 0x06000BAF RID: 2991 RVA: 0x00044950 File Offset: 0x00042B50
		public static byte[] PackToSAMCommand(byte[] command)
		{
			byte[] array = new byte[command.Length + 8];
			array[0] = 170;
			array[1] = 170;
			array[2] = 170;
			array[3] = 150;
			array[4] = 105;
			array[5] = BitConverter.GetBytes(array.Length - 7)[1];
			array[6] = BitConverter.GetBytes(array.Length - 7)[0];
			command.CopyTo(array, 7);
			int num = 0;
			for (int i = 5; i < array.Length - 1; i++)
			{
				num ^= (int)array[i];
			}
			array[array.Length - 1] = (byte)num;
			return array;
		}

		/// <summary>
		/// 根据SAM的实际的指令，来生成实际的指令信息
		/// </summary>
		/// <param name="cmd">命令码</param>
		/// <param name="para">参数信息</param>
		/// <param name="data">数据内容</param>
		/// <returns>字符串的结果信息</returns>
		// Token: 0x06000BB0 RID: 2992 RVA: 0x000449E4 File Offset: 0x00042BE4
		public static byte[] BuildReadCommand(byte cmd, byte para, byte[] data)
		{
			bool flag = data == null;
			if (flag)
			{
				data = new byte[0];
			}
			byte[] array = new byte[2 + data.Length];
			array[0] = cmd;
			array[1] = para;
			data.CopyTo(array, 2);
			return array;
		}

		/// <summary>
		/// 检查当前的接收数据信息是否一条完整的数据信息
		/// </summary>
		/// <param name="input">输入的信息</param>
		/// <returns>是否接收完成</returns>
		// Token: 0x06000BB1 RID: 2993 RVA: 0x00044A24 File Offset: 0x00042C24
		public static bool CheckADSCommandCompletion(List<byte> input)
		{
			bool flag = input != null && input.Count < 8;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				bool flag2 = (int)input[5] * 256 + (int)input[6] > input.Count - 7;
				result = !flag2;
			}
			return result;
		}

		/// <summary>
		/// 检查当前的指令是否是正确的
		/// </summary>
		/// <param name="input">输入的指令信息</param>
		/// <returns>是否校验成功</returns>
		// Token: 0x06000BB2 RID: 2994 RVA: 0x00044A78 File Offset: 0x00042C78
		public static OperateResult CheckADSCommandAndSum(byte[] input)
		{
			bool flag = input != null && input.Length < 8;
			OperateResult result;
			if (flag)
			{
				result = new OperateResult(StringResources.Language.SAMReceiveLengthMustLargerThan8);
			}
			else
			{
				bool flag2 = input[0] != 170 || input[1] != 170 || input[2] != 170 || input[3] != 150 || input[4] != 105;
				if (flag2)
				{
					result = new OperateResult(StringResources.Language.SAMHeadCheckFailed);
				}
				else
				{
					bool flag3 = (int)input[5] * 256 + (int)input[6] != input.Length - 7;
					if (flag3)
					{
						result = new OperateResult(StringResources.Language.SAMLengthCheckFailed);
					}
					else
					{
						int num = 0;
						for (int i = 5; i < input.Length - 1; i++)
						{
							num ^= (int)input[i];
						}
						bool flag4 = num != (int)input[input.Length - 1];
						if (flag4)
						{
							result = new OperateResult(StringResources.Language.SAMSumCheckFailed);
						}
						else
						{
							result = OperateResult.CreateSuccessResult();
						}
					}
				}
			}
			return result;
		}

		/// <summary>
		/// 提炼安全的模块数据信息
		/// </summary>
		/// <param name="data">数据</param>
		/// <returns>结果对象</returns>
		// Token: 0x06000BB3 RID: 2995 RVA: 0x00044B7C File Offset: 0x00042D7C
		public static OperateResult<string> ExtractSafeModuleNumber(byte[] data)
		{
			OperateResult<string> result;
			try
			{
				bool flag = data[9] != 144;
				if (flag)
				{
					result = new OperateResult<string>(SAMSerial.GetErrorDescription((int)data[9]));
				}
				else
				{
					StringBuilder stringBuilder = new StringBuilder();
					stringBuilder.Append(data[10].ToString("D2"));
					stringBuilder.Append(".");
					stringBuilder.Append(data[12].ToString("D2"));
					stringBuilder.Append("-");
					stringBuilder.Append(BitConverter.ToInt32(data, 14).ToString());
					stringBuilder.Append("-");
					stringBuilder.Append(BitConverter.ToInt32(data, 18).ToString("D9"));
					stringBuilder.Append("-");
					stringBuilder.Append(BitConverter.ToInt32(data, 22).ToString("D9"));
					result = OperateResult.CreateSuccessResult<string>(stringBuilder.ToString());
				}
			}
			catch (Exception ex)
			{
				result = new OperateResult<string>("Error:" + ex.Message + "  Source Data: " + SoftBasic.ByteToHexString(data));
			}
			return result;
		}

		/// <summary>
		/// 从数据中提取出真实的身份证信息
		/// </summary>
		/// <param name="data">原始数据内容</param>
		/// <returns>包含结果对象的身份证数据</returns>
		// Token: 0x06000BB4 RID: 2996 RVA: 0x00044CB0 File Offset: 0x00042EB0
		public static OperateResult<IdentityCard> ExtractIdentityCard(byte[] data)
		{
			OperateResult<IdentityCard> result;
			try
			{
				bool flag = data[9] != 144;
				if (flag)
				{
					result = new OperateResult<IdentityCard>(SAMSerial.GetErrorDescription((int)data[9]));
				}
				else
				{
					string @string = Encoding.Unicode.GetString(data, 14, 256);
					byte[] portrait = SoftBasic.ArraySelectMiddle<byte>(data, 270, 1024);
					result = OperateResult.CreateSuccessResult<IdentityCard>(new IdentityCard
					{
						Name = @string.Substring(0, 15),
						Sex = ((@string.Substring(15, 1) == "1") ? "男" : ((@string.Substring(15, 1) == "2") ? "女" : "未知")),
						Nation = SAMSerial.GetNationText(Convert.ToInt32(@string.Substring(16, 2))),
						Birthday = new DateTime(int.Parse(@string.Substring(18, 4)), int.Parse(@string.Substring(22, 2)), int.Parse(@string.Substring(24, 2))),
						Address = @string.Substring(26, 35),
						Id = @string.Substring(61, 18),
						Organ = @string.Substring(79, 15),
						ValidityStartDate = new DateTime(int.Parse(@string.Substring(94, 4)), int.Parse(@string.Substring(98, 2)), int.Parse(@string.Substring(100, 2))),
						ValidityEndDate = new DateTime(int.Parse(@string.Substring(102, 4)), int.Parse(@string.Substring(106, 2)), int.Parse(@string.Substring(108, 2))),
						Portrait = portrait
					});
				}
			}
			catch (Exception ex)
			{
				result = new OperateResult<IdentityCard>(ex.Message);
			}
			return result;
		}

		/// <summary>
		/// 根据民族的代号来获取到民族的文本描述信息
		/// </summary>
		/// <param name="nation">民族代码</param>
		/// <returns>民族的文本信息</returns>
		// Token: 0x06000BB5 RID: 2997 RVA: 0x00044E98 File Offset: 0x00043098
		public static string GetNationText(int nation)
		{
			switch (nation)
			{
			case 1:
				return "汉";
			case 2:
				return "蒙古";
			case 3:
				return "回";
			case 4:
				return "藏";
			case 5:
				return "维吾尔";
			case 6:
				return "苗";
			case 7:
				return "彝";
			case 8:
				return "壮";
			case 9:
				return "布依";
			case 10:
				return "朝鲜";
			case 11:
				return "满";
			case 12:
				return "侗";
			case 13:
				return "瑶";
			case 14:
				return "白";
			case 15:
				return "土家";
			case 16:
				return "哈尼";
			case 17:
				return "哈萨克";
			case 18:
				return "傣";
			case 19:
				return "黎";
			case 20:
				return "傈僳";
			case 21:
				return "佤";
			case 22:
				return "畲";
			case 23:
				return "高山";
			case 24:
				return "拉祜";
			case 25:
				return "水";
			case 26:
				return "东乡";
			case 27:
				return "纳西";
			case 28:
				return "景颇";
			case 29:
				return "柯尔克孜";
			case 30:
				return "土";
			case 31:
				return "达斡尔";
			case 32:
				return "仫佬";
			case 33:
				return "羌";
			case 34:
				return "布朗";
			case 35:
				return "撒拉";
			case 36:
				return "毛南";
			case 37:
				return "仡佬";
			case 38:
				return "锡伯";
			case 39:
				return "阿昌";
			case 40:
				return "普米";
			case 41:
				return "塔吉克";
			case 42:
				return "怒";
			case 43:
				return "乌孜别克";
			case 44:
				return "俄罗斯";
			case 45:
				return "鄂温克";
			case 46:
				return "德昂";
			case 47:
				return "保安";
			case 48:
				return "裕固";
			case 49:
				return "京";
			case 50:
				return "塔塔尔";
			case 51:
				return "独龙";
			case 52:
				return "鄂伦春";
			case 53:
				return "赫哲";
			case 54:
				return "门巴";
			case 55:
				return "珞巴";
			case 56:
				return "基诺";
			case 97:
				return "其他";
			case 98:
				return "外国血统中国籍人士";
			}
			return string.Empty;
		}

		/// <summary>
		/// 枚举当前的所有的民族信息，共计五十六个民族
		/// </summary>
		/// <returns>枚举信息</returns>
		// Token: 0x06000BB6 RID: 2998 RVA: 0x00045299 File Offset: 0x00043499
		public static IEnumerator<string> GetNationEnumerator()
		{
			int num;
			for (int i = 1; i < 57; i = num + 1)
			{
				yield return SAMSerial.GetNationText(i);
				num = i;
			}
			yield break;
		}

		/// <summary>
		/// 获取错误的文本信息
		/// </summary>
		/// <param name="err">错误号</param>
		/// <returns>错误信息</returns>
		// Token: 0x06000BB7 RID: 2999 RVA: 0x000452A4 File Offset: 0x000434A4
		public static string GetErrorDescription(int err)
		{
			if (err <= 65)
			{
				if (err <= 36)
				{
					if (err == 16)
					{
						return StringResources.Language.SAMStatus10;
					}
					if (err == 17)
					{
						return StringResources.Language.SAMStatus11;
					}
					switch (err)
					{
					case 33:
						return StringResources.Language.SAMStatus21;
					case 35:
						return StringResources.Language.SAMStatus23;
					case 36:
						return StringResources.Language.SAMStatus24;
					}
				}
				else
				{
					switch (err)
					{
					case 49:
						return StringResources.Language.SAMStatus31;
					case 50:
						return StringResources.Language.SAMStatus32;
					case 51:
						return StringResources.Language.SAMStatus33;
					default:
						if (err == 64)
						{
							return StringResources.Language.SAMStatus40;
						}
						if (err == 65)
						{
							return StringResources.Language.SAMStatus41;
						}
						break;
					}
				}
			}
			else if (err <= 102)
			{
				if (err == 71)
				{
					return StringResources.Language.SAMStatus47;
				}
				if (err == 96)
				{
					return StringResources.Language.SAMStatus60;
				}
				if (err == 102)
				{
					return StringResources.Language.SAMStatus66;
				}
			}
			else
			{
				if (err == 128)
				{
					return StringResources.Language.SAMStatus80;
				}
				if (err == 129)
				{
					return StringResources.Language.SAMStatus81;
				}
				if (err == 145)
				{
					return StringResources.Language.SAMStatus91;
				}
			}
			return StringResources.Language.UnknownError;
		}
	}
}
